#pragma once
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

using boost::asio::ip::tcp;
namespace ssl = boost::asio::ssl;
typedef ssl::stream<tcp::socket> ssl_socket;

class SSL_Client {
public:
    //发起ssl连接与握手 这个类不保存  io_context context 
    SSL_Client(boost::asio::io_context& io_context, ssl::context& context,
    const std::string& server, const std::string& port)
        :io_context_(&io_context), context_(&context)
    {
        socket_ = new ssl_socket(io_context, context);
        tcp::resolver resolver(io_context);
        endpoint = resolver.resolve(server, port);
        boost::asio::connect(socket_->lowest_layer(), endpoint);
        socket_->handshake(ssl::stream_base::client);
    }
    //发请求报文
    void sendRequest(const std::string& request) {
        boost::asio::write(*socket_, boost::asio::buffer(request));
    }
    //重连未通过测试
    void reconnect()
    {
        socket_->lowest_layer().close();
        delete socket_;
        socket_ = new  ssl_socket(*io_context_, *context_);
        boost::asio::connect(socket_->lowest_layer(), endpoint);

        socket_->handshake(ssl::stream_base::client);
        // std::cout<<"重新连接服务器"<<std::endl;

    }
    //发送响应报文 
    std::string readResponse()
    {
        std::string str;
        std::string ck;
        while (true)
        {
            boost::asio::streambuf response;
            boost::system::error_code ec;
            boost::asio::read_until(*socket_, response, "\r\n", ec);
            //重连
            if (ec == boost::asio::error::connection_reset || ec == boost::asio::error::eof)
            {

                reconnect();
                std::string tem;
                tem.resize(0);
                return tem;
            }
            std::string tem;
            tem.resize(response.size());
            boost::asio::buffer_copy(boost::asio::buffer(tem), response.data());

            std::stringstream ss;
            ss << &response;
            ss >> ck;
            //检查是否拿完
            if (ck == "0")break;
            str += tem;
        }
       
        return str;
    }
    ~SSL_Client()
    {
        delete socket_;
    }
private:
    boost::asio::io_context* io_context_;
    ssl::context* context_;
    ssl_socket* socket_;
    boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> endpoint;
};
